package org.pih.javarosa.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;

import org.javarosa.core.api.State;
import org.javarosa.core.model.FormDef;
import org.javarosa.core.model.instance.FormInstance;
import org.javarosa.core.model.utils.DateUtils;
import org.javarosa.core.services.storage.IStorageIterator;
import org.javarosa.core.services.storage.IStorageUtility;
import org.javarosa.core.services.storage.StorageFullException;
import org.javarosa.core.services.storage.StorageManager;
import org.javarosa.core.util.OrderedHashtable;
import org.javarosa.patient.model.Patient;
import org.pih.javarosa.applogic.AdultDosageContext;
import org.pih.javarosa.applogic.AdultDosageDrugListState;
import org.pih.javarosa.applogic.AdultDosageFormListState;
import org.pih.javarosa.applogic.AdultDosageSavedFormListState;
import org.pih.javarosa.applogic.AdultDosageSplashScreenState;
import org.pih.javarosa.model.Drug;

public class AdultDosageUtil {

	static OrderedHashtable formList;
	private static OrderedHashtable savedFormList;
	private static OrderedHashtable drugList;
	private static OrderedHashtable countryList;
	private static Hashtable drugListData;
	
	public static String getAppProperty(String key) {
		return AdultDosageContext._().getMidlet().getAppProperty(key);
	}

	public static void start() {
		new AdultDosageSplashScreenState().start();
	}

	public static void exit() {
		AdultDosageContext._().getMidlet().notifyDestroyed();
	}

	public static void goToList(boolean formList) {
//		((State) (formList ? new AdultDosageFormListState()
//				: new AdultDosageSavedFormListState())).start();
		// TODO add logic here to 
//		formList = new OrderedHashtable();
//		IStorageUtility forms = StorageManager
//				.getStorage(FormDef.STORAGE_KEY);

		
		new AdultDosageDrugListState();
	
	}

	/**
	 * 
	 * generate and store in RMS several sample patients from the file
	 * "testpatients"
	 * 
	 * 
	 * @param prms
	 */
	public static void loadDrugs(IStorageUtility drugs) {
		System.out.println("inside loadDrugs");
		
		final String drugsFile = "/drugs.txt";

		System.out.println("Initializing the drugs");

		// read test patient data into byte buffer
		byte[] buffer = new byte[4000]; // make sure buffer is big enough for
										// entire file; it will not grow
		// to file size (budget 40 bytes per patient)
		InputStream is = System.class.getResourceAsStream(drugsFile);
		if (is == null) {
			String err = "Drug data file: " + drugsFile
					+ " not found";
			System.out.println(err);
			throw new RuntimeException(err);
		}

		System.out.println("inside loadDrugs 2");

		int len = 0;
		try {
			len = is.read(buffer);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage());
		}

		System.out.println("inside loadDrugs 3");

		// copy byte buffer into character string
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < len; i++)
			sb.append((char) buffer[i]);
		buffer = null;
		String data = sb.toString();

		System.out.println("inside loadDrugs 3");

		// split lines
		Vector lines = DateUtils.split(data, "\n", false);
		data = null;

		
		System.out.println("inside loadDrugs 4");

		// parse drugs
		for (int i = 0; i < lines.size(); i++) {
			String line = (String) lines.elementAt(i);
System.out.println("inside loadDrugs line: " + line);

			if (line.trim().length() == 0)
				continue;
			Vector drugRow = DateUtils.split(line, "|", false);
			if (drugRow.size() != 2)
				throw new RuntimeException("Malformed drug data at line: "
						+ (i + 1));

			try {
				
				Drug drug = parseDrugRow(i, drugRow);
System.out.println("Adding drug: " + drug.getID() + " :: " + drug.getName() + " / " + drug.getProtocolXFormPath());
				drug.setID(i + 1);
				drugs.write(drug);
			} catch (StorageFullException e) {
				throw new RuntimeException("uh-oh, storage full [drugs]"); // TODO:
																				// handle
																				// this
			}
		}

		System.out.println("inside loadDrugs 5");
	
	}


	
	
	/**
	 * 
	 * generate and store in RMS several sample patients from the file
	 * "testpatients"
	 * 
	 * 
	 * @param prms
	 */
	public static void loadDemoPatients(IStorageUtility patients) {
		final String patientsFile = "/testpatients";

		//#debug debug
		System.out.println("Initializing the test patients ");

		// read test patient data into byte buffer
		byte[] buffer = new byte[4000]; // make sure buffer is big enough for
										// entire file; it will not grow
		// to file size (budget 40 bytes per patient)
		InputStream is = System.class.getResourceAsStream(patientsFile);
		if (is == null) {
			String err = "Test patient data file: " + patientsFile
					+ " not found";
			//#debug error
			System.out.println(err);
			throw new RuntimeException(err);
		}

		int len = 0;
		try {
			len = is.read(buffer);
		} catch (IOException e) {
			//#debug error
			throw new RuntimeException(e.getMessage());
		}

		// copy byte buffer into character string
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < len; i++)
			sb.append((char) buffer[i]);
		buffer = null;
		String data = sb.toString();

		// split lines
		Vector lines = DateUtils.split(data, "\n", false);
		data = null;

		// parse patients
		for (int i = 0; i < lines.size(); i++) {
			String line = (String) lines.elementAt(i);
			if (line.trim().length() == 0)
				continue;
			Vector pat = DateUtils.split(line, "|", false);
			if (pat.size() != 6)
				throw new RuntimeException("Malformed patient data at line: "
						+ (i + 1));

			try {
				patients.write(parseSinglePatient(i, pat));
			} catch (StorageFullException e) {
				throw new RuntimeException("uh-oh, storage full [patients]"); // TODO:
																				// handle
																				// this
			}
		}
	}

	private static Patient parseSinglePatient(int i, Vector pat) {
		Patient p = new Patient();
		p.setFamilyName((String) pat.elementAt(0));
		p.setGivenName((String) pat.elementAt(1));
		p.setMiddleName((String) pat.elementAt(2));
		p.setPatientIdentifier((String) pat.elementAt(3));
		p.setGender("m".equals((String) pat.elementAt(4)) ? Patient.SEX_MALE
				: Patient.SEX_FEMALE);
		p.setBirthDate(DateUtils.dateAdd(DateUtils.today(), -Integer
				.parseInt((String) pat.elementAt(5))));
		return p;
	}

	private static Drug parseDrugRow(int i, Vector drugData) {
		Drug drug = new Drug();
		drug.setName((String) drugData.elementAt(0));
		drug.setProtocolXFormPath(((String) drugData.elementAt(1)).replace('\r', ' ').trim());
		return drug;
	}

	// cache this because the storage utility doesn't yet support quick
	// meta-data iteration
	public static OrderedHashtable getFormList() {
		if (formList == null) {
			formList = new OrderedHashtable();
			IStorageUtility forms = StorageManager
					.getStorage(FormDef.STORAGE_KEY);
			IStorageIterator fi = forms.iterate();
			while (fi.hasMore()) {
				FormDef f = (FormDef) fi.nextRecord();
				formList.put(new Integer(f.getID()), f.getTitle());
			}
		}
		return formList;
	}

	// cache this because the storage utility doesn't yet support quick
	// meta-data iteration
	public static OrderedHashtable getSavedFormList() {
		if (savedFormList == null) {
			savedFormList = new OrderedHashtable();
			IStorageUtility forms = StorageManager
					.getStorage(FormInstance.STORAGE_KEY);
			IStorageIterator fi = forms.iterate();
			while (fi.hasMore()) {
				FormInstance f = (FormInstance) fi.nextRecord();
				System.out.println("adding saved form: " + f.getID() + " - "
						+ f.getName() + " - " + f.getFormId());
				savedFormList.put(new Integer(f.getID()), f.getName());
			}
		}
		return savedFormList;
	}
	
	public static OrderedHashtable getDrugList() {
		if (drugList == null) {
			final String drugsFile = "/drugs.txt";

			System.out.println("Initializing the drugs");

			// read test patient data into byte buffer
			byte[] buffer = new byte[4000]; // make sure buffer is big enough for
											// entire file; it will not grow
			// to file size (budget 40 bytes per patient)
			InputStream is = System.class.getResourceAsStream(drugsFile);
			if (is == null) {
				String err = "Drug data file: " + drugsFile
						+ " not found";
				System.out.println(err);
				throw new RuntimeException(err);
			}

			System.out.println("inside loadDrugs 2");

			int len = 0;
			try {
				len = is.read(buffer);
			} catch (IOException e) {
				throw new RuntimeException(e.getMessage());
			}

			System.out.println("inside loadDrugs 3");

			// copy byte buffer into character string
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < len; i++)
				sb.append((char) buffer[i]);
			buffer = null;
			String data = sb.toString();

			System.out.println("inside loadDrugs 3");

			// split lines
			Vector lines = DateUtils.split(data, "\n", false);
			data = null;

			
			System.out.println("inside loadDrugs 4");

			drugList = new OrderedHashtable();
			drugListData = new Hashtable<Integer, Drug>();

			
			// parse drugs
			for (int i = 0; i < lines.size(); i++) {
				String line = (String) lines.elementAt(i);
	System.out.println("inside loadDrugs line: " + line);

				if (line.trim().length() == 0)
					continue;
				Vector drugRow = DateUtils.split(line, "|", false);
				if (drugRow.size() != 2)
					throw new RuntimeException("Malformed drug data at line: "
							+ (i + 1));

					Drug drug = parseDrugRow(i, drugRow);
					drug.setID(i + 1);
	System.out.println("Adding drug: " + drug.getID() + " :: " + drug.getName() + " / " + drug.getProtocolXFormPath());
					drugList.put(new Integer(drug.getID()), drug.getName());
					drugListData.put(new Integer(drug.getID()), drug);
			}
			
		}
		return drugList;
	}
	public static OrderedHashtable getCountryList() {
		if (drugList == null) {
			final String countryFile = "/countries.txt";

			System.out.println("Initializing the countries");

			// read test patient data into byte buffer
			byte[] buffer = new byte[4000]; // make sure buffer is big enough for
											// entire file; it will not grow
			// to file size (budget 40 bytes per patient)
			InputStream is = System.class.getResourceAsStream(countryFile);
			if (is == null) {
				String err = "Country data file: " + countryFile
						+ " not found";
				System.out.println(err);
				throw new RuntimeException(err);
			}

			System.out.println("inside getCountryList 2");

			int len = 0;
			try {
				len = is.read(buffer);
			} catch (IOException e) {
				throw new RuntimeException(e.getMessage());
			}

			System.out.println("inside getCountryList 3");

			// copy byte buffer into character string
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < len; i++)
				sb.append((char) buffer[i]);
			buffer = null;
			String data = sb.toString();

			System.out.println("inside getCountryList 3");

			// split lines
			Vector lines = DateUtils.split(data, "\n", false);
			data = null;

			
			System.out.println("inside getCountryList 4");

			countryList = new OrderedHashtable();

			
			// parse drugs
			for (int i = 0; i < lines.size(); i++) {
				String line = (String) lines.elementAt(i);
	System.out.println("inside getCountryList line: " + line);

				if (line.trim().length() == 0)
					continue;
				Vector countryRow = DateUtils.split(line, "|", false);
				if (countryRow.size() != 2)
					throw new RuntimeException("Malformed country data at line: "
							+ (i + 1));

					String country = (String) countryRow.elementAt(0);
	System.out.println("Adding getCountryList: " + (i + 1) + " :: " + country);
					countryList.put(new Integer(i + 1), country);
			}
			
		}
		return countryList;
	}

	public static Hashtable<Integer, Drug> getDrugListData() {
		return drugListData;
	}
}
